#ifndef MEM_H
#define MEM_H
#include "types.h"
#include "bitmap.h"
#include "mutex.h"
#include "boot_info.h"

#define MEM_EXT_START (1024*1024)
#define MEM_PAGE_SIZE 4096
//not used mem start addr
#define MEM_EBDA_START 0x80000
#define MEM_TASK_BASE  0x80000000
#define MEM_EXT_END    (200 * 1024 *1024)
#define MEM_TASK_STACK_TOP 0xE0000000
#define MEM_TASK_STACK_SIZE (500*MEM_PAGE_SIZE)
#define MEM_TASK_ARG_SIZE   (4*MEM_PAGE_SIZE)

typedef struct _addr_alloc_t{
    mutex_t mutex;
    bitmap_t bitmap;

    uint32_t start;
    uint32_t size;//the size of mem need to manage
    uint32_t page_size;//the size of page, 1kb or 4kb

}addr_alloc_t;

typedef struct _mem_map_t{
    void * vstart;
    void * vend; //the end, but not include
    void * pstart;
    uint32_t perm;//about privilege, permission
}mem_map_t;

void mem_init(boot_info_t * boot_info);
uint32_t mem_create_uvm(void);

int mem_alloc_page_for(uint32_t vaddr,uint32_t size,int perm);
int mem_alloc_for_page_dir(uint32_t page_dir,uint32_t vaddr,uint32_t size,int perm);
uint32_t mem_alloc_page(void);
void mem_free_page(uint32_t addr);

uint32_t mem_copy_uvm(uint32_t page_dir);
void mem_destroy_uvm(uint32_t page_dir);


uint32_t mem_get_paddr(uint32_t page_dir,uint32_t vaddr);
//the page_dir has not been used yet
int mem_copy_uvm_data(uint32_t to,uint32_t page_dir,uint32_t from,int size);

char* sys_sbrk(int incr);

#endif // !MEM_H